﻿namespace EFS.Common.UI.Win32
{
	public static class WindowHelper
	{
		#region Win32 Api

		private const System.Int32 GWL_STYLE = -16;
		private const System.Int32 WS_SYSMENU = 0x80000;
		private const System.Int32 WS_MAXIMIZEBOX = 0x00010000;
		private const System.Int32 WS_MINIMIZEBOX = 0x00020000;

		/// <summary>
		/// Platform switch for GetWindowLong
		/// </summary>
		/// <param name="hWnd"></param>
		/// <param name="nIndex"></param>
		/// <returns></returns>
		private static System.Int32 GetWindowLong(System.IntPtr hWnd, int nIndex)
		{
			return (System.IntPtr.Size == 4) ? GetWindowLong32(hWnd, nIndex) : GetWindowLong64(hWnd, nIndex);
		}

		/// <summary>
		/// Platform switch for SetWindowLong
		/// </summary>
		/// <param name="hWnd"></param>
		/// <param name="nIndex"></param>
		/// <returns></returns>
		private static System.Int32 SetWindowLong(System.IntPtr hWnd, System.Int32 nIndex, System.Int32 dwNewLong)
		{
			return (System.IntPtr.Size == 4) ? SetWindowLong32(hWnd, nIndex, dwNewLong) : SetWindowLong64(hWnd, nIndex, dwNewLong);
		}

		[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
		private static extern System.Int32 GetWindowLong32(System.IntPtr hWnd, System.Int32 nIndex);

		[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
		private static extern System.Int32 GetWindowLong64(System.IntPtr hWnd, System.Int32 nIndex);

		[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "SetWindowLong")]
		private extern static System.Int32 SetWindowLong32(System.IntPtr hWnd, System.Int32 nIndex, System.Int32 dwNewLong);

		[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "SetWindowLong")]
		private extern static System.Int32 SetWindowLong64(System.IntPtr hWnd, System.Int32 nIndex, System.Int32 dwNewLong);

		#endregion

		/// <summary>
		/// Disables the close functionality.
		/// </summary>
		///The WPF window to be modified.
		public static System.Boolean IsDisposed(System.Windows.Window window)
		{
			lock (window)
			{
				return null == new System.Windows.Interop.WindowInteropHelper(window).Handle;
			}
		}

		/// <summary>
		/// Disables the close functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void DisableClose(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);
				SetWindowLong(hWnd, GWL_STYLE, windowStyle & ~WS_SYSMENU);
			}
		}

		/// <summary>
		/// Disables the maximize functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void DisableMaximize(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);
				SetWindowLong(hWnd, GWL_STYLE, windowStyle & ~WS_MAXIMIZEBOX);
			}
		}

		/// <summary>
		/// Disables the minimize functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void DisableMinimize(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);
				SetWindowLong(hWnd, GWL_STYLE, windowStyle & ~WS_MINIMIZEBOX);
			}
		}

		/// <summary>
		/// Enables the close functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void EnableClose(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);
				SetWindowLong(hWnd, GWL_STYLE, windowStyle | WS_SYSMENU);
			}
		}

		/// <summary>
		/// Enables the maximize functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void EnableMaximize(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);
				SetWindowLong(hWnd, GWL_STYLE, windowStyle | WS_MAXIMIZEBOX);
			}
		}

		/// <summary>
		/// Enables the minimize functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void EnableMinimize(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);
				SetWindowLong(hWnd, GWL_STYLE, windowStyle | WS_MINIMIZEBOX);
			}
		}

		/// <summary>
		/// Toggles the enabled state close functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void ToggleClose(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);

				if ((windowStyle | WS_SYSMENU) == windowStyle)
				{
					SetWindowLong(hWnd, GWL_STYLE, windowStyle & ~WS_SYSMENU);
				}
				else
				{
					SetWindowLong(hWnd, GWL_STYLE, windowStyle | WS_SYSMENU);
				}
			}
		}

		/// <summary>
		/// Toggles the enabled state maximize functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void ToggleMaximize(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);

				if ((windowStyle | WS_MAXIMIZEBOX) == windowStyle)
				{
					SetWindowLong(hWnd, GWL_STYLE, windowStyle & ~WS_MAXIMIZEBOX);
				}
				else
				{
					SetWindowLong(hWnd, GWL_STYLE, windowStyle | WS_MAXIMIZEBOX);
				}
			}
		}

		/// <summary>
		/// Toggles the enabled state minimize functionality.
		/// </summary>
		///The WPF window to be modified.
		public static void ToggleMinimize(System.Windows.Window window)
		{
			lock (window)
			{
				System.IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
				System.Int32 windowStyle = GetWindowLong(hWnd, GWL_STYLE);

				if ((windowStyle | WS_MINIMIZEBOX) == windowStyle)
				{
					SetWindowLong(hWnd, GWL_STYLE, windowStyle & ~WS_MINIMIZEBOX);
				}
				else
				{
					SetWindowLong(hWnd, GWL_STYLE, windowStyle | WS_MINIMIZEBOX);
				}
			}
		}
	}
}